﻿using AutoMapper;
using IOA.MES.Common;
using IOA.MES.DataAccess.Entity;
using IOA.MES.DataAccess.Enum;
using IOA.MES.DataAccess.VModel;
using IOA.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace IOA.MES.Business
{
    /// <summary>
    /// 仓库管理（错误代码：103001）
    /// </summary>
    public class WarehouseMgr
    {
        private MESContext mesDb = new MESContext("MES");

        public List<VWarehouse> QueryWarehouses()
        {
            var entities = mesDb.Warehouses.Where(_ => _.Valid).ToList();
            var models = Mapper.Map<List<VWarehouse>>(entities);
            return models;
        }

        /// <summary>
        /// 获取仓库对象
        /// </summary>
        /// <param name="warehouseId">仓库ID</param>
        /// <returns>仓库对象</returns>
        public VWarehouse GetWarehouse(int warehouseId)
        {
            var entity = mesDb.Warehouses.FirstOrDefault(_ => _.PkId == warehouseId && _.Valid);
            return Mapper.Map<VWarehouse>(entity);
        }

        /// <summary>
        /// 获取仓库对象
        /// </summary>
        /// <param name="warehouseCode">仓库代码</param>
        /// <returns>仓库对象</returns>
        public VWarehouse GetWarehouse(string warehouseCode)
        {
            var entity = mesDb.Warehouses.FirstOrDefault(_ => _.WarehouseCode == warehouseCode && _.Valid);
            return Mapper.Map<VWarehouse>(entity);
        }

        /// <summary>
        /// 根据工单号查找仓库
        /// </summary>
        /// <param name="workOrderNo">工单号</param>
        public VWarehouse GetWarehouseByWorkOrderNo(string workOrderNo)
        {
            var entity = (from a in mesDb.WorkOrders.Where(_ => _.WorkOrderNo == workOrderNo && _.Valid)
                          join b in mesDb.Warehouses.Where(_ => _.Valid) on a.WorkshopCode equals b.WorkshopCode
                          select b).FirstOrDefault();
            return Mapper.Map<VWarehouse>(entity);
        }

        /// <summary>
        /// 根据车间代码查找仓库
        /// </summary>
        /// <param name="workshopCode">车间代码</param>
        public VWarehouse GetWarehouseByWorkshopCode(string workshopCode)
        {
            var entity = mesDb.Warehouses.AsNoTracking().FirstOrDefault(_ => _.WorkshopCode == workshopCode && _.Valid);
            return Mapper.Map<VWarehouse>(entity);
        }

        /// <summary>
        /// 获取组件车间仓库存
        /// </summary>
        /// <param name="code">组件条码</param>
        /// <returns>车间仓库存</returns>
        public List<VStorage> QueryProductWorkshopWarehouseStorages(string code)
        {
            var entity = mesDb.Components.AsNoTracking().FirstOrDefault(_ => _.BarCode == code && _.Valid);
            if (entity == null)
            {
                throw new MultiLanBizException(103001);// "条码不存在");
            }
            var warehouse = mesDb.Warehouses.AsNoTracking().FirstOrDefault(_ => _.WarehouseType == WarehouseType.Workshop && _.WorkshopCode == entity.WorkshopCode && _.Valid);
            if (warehouse == null)
            {
                throw new MultiLanBizException(103015, entity.WorkshopName);// "当前车间不存在线边仓，请联系IT"
            }
            return QueryWarehouseStorages(warehouse.WarehouseCode);
        }

        /// <summary>
        /// 查询仓库库存
        /// </summary>
        /// <param name="warehouseCode">仓库代码</param>
        /// <returns>库存列表</returns>
        public List<VStorage> QueryWarehouseStorages(string warehouseCode)
        {
            var entities = mesDb.Storages.AsNoTracking().Where(_ => _.WarehouseCode == warehouseCode && _.Quantity > 0 && _.Valid).ToList();
            return Mapper.Map<List<VStorage>>(entities);
        }

        /// <summary>
        /// 编辑仓库
        /// </summary>
        /// <param name="model">仓库对象</param>
        public void EditWarehouse(VWarehouse model)
        {
            if (model.WarehouseType != WarehouseType.Workshop)
            {
                model.WorkshopCode = string.Empty;
            }
            if (model.PkId <= 0)
            {
                var exist = mesDb.Warehouses.AsNoTracking().FirstOrDefault(_ => (_.WarehouseCode == model.WarehouseCode || _.WarehouseName == model.WarehouseName) && _.Valid);
                if (exist != null)
                {
                    if (StringUtils.Equals(exist.WarehouseCode, model.WarehouseCode))
                    {
                        throw new MultiLanBizException(103002);// "仓库代码已存在");
                    }
                    else
                    {
                        throw new MultiLanBizException(103003);// "仓库名称已存在");
                    }
                }

                model.CreateTime = DateTime.Now;
                model.Status = CommonStatus.Normal;
                var entity = Mapper.Map<Warehouse>(model);
                mesDb.Warehouses.Add(entity);
                mesDb.SaveChanges();
            }
            else
            {
                var exist = mesDb.Warehouses.FirstOrDefault(_ => _.PkId != model.PkId && (_.WarehouseCode == model.WarehouseCode || _.WarehouseName == model.WarehouseName) && _.Valid);
                if (exist != null)
                {
                    if (StringUtils.Equals(exist.WarehouseCode, model.WarehouseCode))
                    {
                        throw new MultiLanBizException(103002);// "仓库代码已存在");
                    }
                    else
                    {
                        throw new MultiLanBizException(103003);// "仓库名称已存在");
                    }
                }
                var entity = mesDb.Warehouses.FirstOrDefault(_ => _.PkId == model.PkId && _.Valid);
                if (entity == null)
                {
                    throw new MultiLanBizException(103004);// "仓库不存在，无法编辑");
                }

                mesDb.Warehouses.Attach(entity);
                entity.WarehouseType = model.WarehouseType;
                entity.WarehouseCode = model.WarehouseCode;
                entity.WarehouseName = model.WarehouseName;
                entity.WorkshopCode = model.WorkshopCode;
                entity.ModifyBy = model.ModifyBy;
                entity.ModifyTime = DateTime.Now;
                mesDb.SaveChanges();
            }
        }

        /// <summary>
        /// 设置默认仓库
        /// </summary>
        /// <param name="model">用户仓库对象</param>
        public void SetDefaultWarehouse(VUserWarehouse model)
        {
            var userWarehouses = mesDb.UserWarehouses.Where(_ => _.UserId == model.UserId && _.Valid).ToList();
            if (!userWarehouses.Any(_ => string.Equals(_.WarehouseCode, model.WarehouseCode, StringComparison.CurrentCultureIgnoreCase)))
            {
                throw new MultiLanBizException(103005);// "当前用户没有这个仓库的权限");
            }
            if (string.Equals(userWarehouses.FirstOrDefault(_ => _.IsDefault)?.WarehouseCode, model.WarehouseCode, StringComparison.CurrentCultureIgnoreCase))
            {
                return;
            }
            userWarehouses.ForEach(_ =>
            {
                _.IsDefault = string.Equals(_.WarehouseCode, model.WarehouseCode, StringComparison.CurrentCultureIgnoreCase);
                if (_.IsDefault)
                {
                    _.ModifyBy = model.ModifyBy;
                    _.ModifyTime = DateTime.Now;
                }
            });
            mesDb.SaveChanges();
        }

        /// <summary>
        /// 查询库区
        /// </summary>
        /// <param name="areaId">区域ID</param>
        /// <returns>库区对象</returns>
        public VWarehouseArea GetWarehouseArea(int areaId, string areaCode = "")
        {
            WarehouseArea entity = null;
            if (areaId > 0)
            {
                entity = mesDb.WarehouseAreas.FirstOrDefault(_ => _.PkId == areaId && _.Valid);
            }
            else if (!string.IsNullOrWhiteSpace(areaCode))
            {
                entity = mesDb.WarehouseAreas.FirstOrDefault(_ => _.AreaCode == areaCode && _.Valid);
            }
            return Mapper.Map<VWarehouseArea>(entity);
        }

        /// <summary>
        /// 编辑库区
        /// </summary>
        /// <param name="model">库区对象</param>
        public void EditWarehouseArea(VWarehouseArea model)
        {
            if (model.PkId <= 0)
            {
                var exist = mesDb.WarehouseAreas.FirstOrDefault(_ => _.WarehouseCode == model.WarehouseCode && (_.AreaCode == model.AreaCode || _.AreaName == model.AreaName) && _.Valid);
                if (exist != null)
                {
                    if (StringUtils.Equals(exist.AreaCode, model.AreaCode))
                    {
                        throw new MultiLanBizException(103006);// "库区代码已存在");
                    }
                    else
                    {
                        throw new MultiLanBizException(103007);// "库区名称已存在");
                    }
                }

                var warehouse = mesDb.Warehouses.FirstOrDefault(_ => _.WarehouseCode == model.WarehouseCode && _.Valid);
                model.WarehouseName = warehouse?.WarehouseName;
                model.CreateTime = DateTime.Now;
                model.Status = CommonStatus.Normal;
                var entity = Mapper.Map<WarehouseArea>(model);
                mesDb.WarehouseAreas.Add(entity);
                mesDb.SaveChanges();
            }
            else
            {
                var exist = mesDb.WarehouseAreas.FirstOrDefault(_ => _.PkId != model.PkId && _.WarehouseCode == model.WarehouseCode && (_.AreaCode == model.AreaCode || _.AreaName == model.AreaName) && _.Valid);
                if (exist != null)
                {
                    if (StringUtils.Equals(exist.AreaCode, model.AreaCode))
                    {
                        throw new MultiLanBizException(103006);// "库区代码已存在");
                    }
                    else
                    {
                        throw new MultiLanBizException(103007);// "库区名称已存在");
                    }
                }
                var entity = mesDb.WarehouseAreas.FirstOrDefault(_ => _.PkId == model.PkId && _.Valid);
                if (entity == null)
                {
                    throw new MultiLanBizException(103008);// "库区不存在，无法编辑");
                }
                var warehouse = mesDb.Warehouses.FirstOrDefault(_ => _.WarehouseCode == model.WarehouseCode && _.Valid);
                model.WarehouseName = warehouse?.WarehouseName;

                mesDb.WarehouseAreas.Attach(entity);
                entity.WarehouseCode = model.WarehouseCode;
                entity.WarehouseName = model.WarehouseName;
                entity.AreaCode = model.AreaCode;
                entity.AreaName = model.AreaName;
                entity.ModifyBy = model.ModifyBy;
                entity.ModifyTime = DateTime.Now;
                mesDb.SaveChanges();
            }
        }

        /// <summary>
        /// 查询库位列表
        /// </summary>
        /// <param name="page">页面索引</param>
        /// <param name="limit">页面容量</param>
        /// <param name="total">总数量</param>
        /// <param name="warehouseCode">仓库代码</param>
        /// <param name="areaCode">库区代码</param>
        /// <param name="key">关键字（库位代码）</param>
        /// <param name="status">状态</param>
        /// <returns>库位列表</returns>
        public List<VWarehouseLocation> QueryWarehouseLocations(int page, int limit, out int total, string warehouseCode, string areaCode, string key, CommonStatus? status)
        {
            var query = from location in mesDb.WarehouseLocations.Where(_ => _.Valid)
                        select location;
            if (!string.IsNullOrWhiteSpace(warehouseCode))
            {
                query = query.Where(_ => _.WarehouseCode == warehouseCode);
            }
            if (!string.IsNullOrWhiteSpace(areaCode))
            {
                query = query.Where(_ => _.AreaCode == areaCode);
            }
            if (!string.IsNullOrWhiteSpace(key))
            {
                query = query.Where(_ => _.Location.Contains(key));
            }
            if (status.HasValue)
            {
                query = query.Where(_ => _.Status == status.Value);
            }

            total = query.Count();

            var entities = query.OrderBy(_ => _.WarehouseCode).ThenBy(_ => _.AreaCode).ThenBy(_ => _.Location).ToList();
            var models = Mapper.Map<List<VWarehouseLocation>>(entities);

            return models;
        }

        /// <summary>
        /// 查询待入库组件
        /// </summary>
        /// <param name="page">页面索引</param>
        /// <param name="limit">页面容量</param>
        /// <param name="workshopCode">车间ID</param>
        /// <param name="orderNo">订单号</param>
        /// <param name="workOrderNo">工单号</param>
        /// <param name="packBatchNo">包装批次号</param>
        /// <param name="packNo">包装号</param>
        /// <param name="startDate">开始日期</param>
        /// <param name="endDate">截止日期</param>
        /// <returns>打包列表</returns>
        public List<VPack> QueryUnInboundPacks(int page, int limit, out int total, string workshopCode, string orderNo, string workOrderNo, string packBatchNo, string packNo, DateTime startDate, DateTime endDate)
        {
            endDate = endDate.AddDays(1);
            var query = from pack in mesDb.Packs.Where(_ => _.Valid && _.PackStatus == PackStatus.Normal && _.PackInspectStatus == PackInboundInspectStatus.Inspected && _.CreateTime >= startDate && _.CreateTime < endDate)
                        select pack;
            if (!string.IsNullOrWhiteSpace(workshopCode))
            {
                query = query.Where(_ => _.WorkshopCode == workshopCode);
            }
            if (!string.IsNullOrWhiteSpace(orderNo))
            {
                query = query.Where(_ => _.OrderNo.Contains(orderNo));
            }
            if (!string.IsNullOrWhiteSpace(workOrderNo))
            {
                query = query.Where(_ => _.WorkOrderNo.Contains(workOrderNo));
            }
            if (!string.IsNullOrWhiteSpace(packBatchNo))
            {
                query = query.Where(_ => _.PackBatchNo.Contains(packBatchNo));
            }
            if (!string.IsNullOrWhiteSpace(packNo))
            {
                query = query.Where(_ => _.PackNo.Contains(packNo));
            }

            total = query.Count();
            query = query.OrderByDescending(_ => _.PkId);
            var entities = limit <= 0 ? query.ToList() : query.Skip((page - 1) * limit).Take(limit).ToList();
            var models = Mapper.Map<List<VPack>>(entities);
            return models;
        }

        /// <summary>
        /// 修改库位状态
        /// </summary>
        /// <param name="model">库位对象</param>
        public void ModifyLocationStatus(VWarehouseLocation model)
        {
            var entity = mesDb.WarehouseLocations.FirstOrDefault(_ => _.PkId == model.PkId && _.Valid);
            if (entity == null)
            {
                throw new MultiLanBizException(103009);// "库位不存在，无法编辑");
            }

            mesDb.WarehouseLocations.Attach(entity);
            entity.Status = model.Status;
            entity.ModifyBy = model.ModifyBy;
            entity.ModifyTime = DateTime.Now;
            mesDb.SaveChanges();
        }

        /// <summary>
        /// 编辑库位
        /// </summary>
        /// <param name="model">库位对象</param>
        public void EditWarehouseLocation(VWarehouseLocation model)
        {
            if (model.PkId <= 0)
            {
                var exist = mesDb.WarehouseLocations.FirstOrDefault(_ => _.WarehouseCode == model.WarehouseCode && _.AreaCode == model.AreaCode && _.Location == model.Location && _.Valid);
                if (exist != null)
                {
                    throw new MultiLanBizException(103010);// "库位已存在");
                }

                var warehouse = mesDb.Warehouses.FirstOrDefault(_ => _.WarehouseCode == model.WarehouseCode && _.Valid);
                var area = mesDb.WarehouseAreas.FirstOrDefault(_ => _.AreaCode == model.AreaCode && _.Valid);
                model.WarehouseName = warehouse?.WarehouseName;
                model.AreaName = area?.AreaName;
                model.CreateTime = DateTime.Now;
                model.Status = CommonStatus.Normal;
                var entity = Mapper.Map<WarehouseLocation>(model);
                mesDb.WarehouseLocations.Add(entity);
                mesDb.SaveChanges();
            }
            else
            {
                var exist = mesDb.WarehouseLocations.FirstOrDefault(_ => _.WarehouseCode == model.WarehouseCode && _.AreaCode == model.AreaCode && _.PkId != model.PkId && _.Location == model.Location && _.Valid);
                if (exist != null)
                {
                    throw new MultiLanBizException(103010);// "库位已存在");
                }
                var entity = mesDb.WarehouseLocations.FirstOrDefault(_ => _.PkId == model.PkId && _.Valid);
                if (entity == null)
                {
                    throw new MultiLanBizException(103009);// "库位不存在，无法编辑");
                }
                var warehouse = mesDb.Warehouses.FirstOrDefault(_ => _.WarehouseCode == model.WarehouseCode && _.Valid);
                var area = mesDb.WarehouseAreas.FirstOrDefault(_ => _.AreaCode == model.AreaCode && _.Valid);
                model.WarehouseName = warehouse?.WarehouseName;
                model.AreaName = area?.AreaName;

                mesDb.WarehouseLocations.Attach(entity);
                entity.WarehouseCode = model.WarehouseCode;
                entity.WarehouseName = model.WarehouseName;
                entity.AreaCode = model.AreaCode;
                entity.AreaName = model.AreaName;
                entity.ModifyBy = model.ModifyBy;
                entity.ModifyTime = DateTime.Now;
                mesDb.SaveChanges();
            }
        }

        /// <summary>
        /// 查询库位库存列表
        /// </summary>
        /// <param name="page">页面索引</param>
        /// <param name="limit">页面容量</param>
        /// <param name="total">全部数量</param>
        /// <param name="warehouseCode">仓库代码</param>
        /// <param name="areaCode">库区代码</param>
        /// <param name="location">库位</param>
        /// <returns>库位库存列表</returns>
        public List<VStorage> QueryLocationStorages(int page, int limit, out int total, string warehouseCode, string areaCode, string location)
        {
            var storageQuery = mesDb.Storages.AsNoTracking().Where(_ => _.InventoryType == InventoryType.ProductPack && _.Quantity > 0 && _.Valid);
            if (!string.IsNullOrWhiteSpace(warehouseCode))
            {
                storageQuery = storageQuery.Where(_ => _.WarehouseCode == warehouseCode);
            }
            if (!string.IsNullOrWhiteSpace(areaCode))
            {
                storageQuery = storageQuery.Where(_ => _.AreaCode == areaCode);
            }
            if (!string.IsNullOrWhiteSpace(location))
            {
                storageQuery = storageQuery.Where(_ => _.Location == location);
            }
            total = storageQuery.Count();
            storageQuery = storageQuery.OrderBy(_ => _.WarehouseCode).ThenBy(_ => _.AreaCode).ThenBy(_ => _.Location);
            var storages = limit <= 0 ? storageQuery.ToList() : storageQuery.Skip((page - 1) * limit).Take(limit).ToList();

            return Mapper.Map<List<VStorage>>(storages);
        }

        /// <summary>
        /// 查看库位
        /// </summary>
        /// <param name="locationId">库位ID</param>
        /// <returns>库位对象</returns>
        public VWarehouseLocation GetWarehouseLocation(int locationId)
        {
            var entity = mesDb.WarehouseLocations.FirstOrDefault(_ => _.PkId == locationId && _.Valid);
            return Mapper.Map<VWarehouseLocation>(entity);
        }

        /// <summary>
        /// 修改库区状态
        /// </summary>
        /// <param name="model">库区对象</param>
        public void ModifyAreaStatus(VWarehouseArea model)
        {
            var entity = mesDb.WarehouseAreas.FirstOrDefault(_ => _.PkId == model.PkId && _.Valid);
            if (entity == null)
            {
                throw new MultiLanBizException(103008);// "库区不存在，无法编辑");
            }

            mesDb.WarehouseAreas.Attach(entity);
            entity.Status = model.Status;
            entity.ModifyBy = model.ModifyBy;
            entity.ModifyTime = DateTime.Now;
            mesDb.SaveChanges();
        }

        /// <summary>
        /// 查询仓库列表
        /// </summary>
        /// <param name="warehouseType">仓库类型</param>
        /// <param name="workshopCode">车间ID</param>
        /// <param name="status">状态</param>
        /// <returns>仓库列表</returns>
        public List<VWarehouse> QueryWarehouses(WarehouseType? warehouseType, string workshopCode, CommonStatus? status)
        {
            var query = from warehouse in mesDb.Warehouses.AsNoTracking().Where(_ => _.Valid)
                        select warehouse;
            if (warehouseType.HasValue)
            {
                query = query.Where(_ => _.WarehouseType == warehouseType.Value);
            }
            //if (workshopCode > -2)
            //{
            //    if (workshopCode == -1)
            //    {
            //        query = query.Where(_ => _.WorkshopCode > 0);
            //    }
            //    else
            //    {
            //        query = query.Where(_ => _.WorkshopCode == workshopCode);
            //    }
            //}
            if (status.HasValue)
            {
                query = query.Where(_ => _.Status == status.Value);
            }

            var entities = query.OrderBy(_ => _.WarehouseName).ToList();
            var models = Mapper.Map<List<VWarehouse>>(entities);

            var workshopCodes = models.Select(_ => _.WorkshopCode).Distinct().ToList();
            var workshops = mesDb.Workshops.Where(_ => workshopCodes.Contains(_.WorkshopCode)).ToList();

            models.ForEach(_ => _.WorkshopName = workshops.FirstOrDefault(w => string.Equals(w.WorkshopCode, _.WorkshopCode, StringComparison.CurrentCultureIgnoreCase))?.WorkshopName);

            return models;
        }

        /// <summary>
        /// 查询库区列表
        /// </summary>
        /// <param name="page">页面索引</param>
        /// <param name="limit">页面容量</param>
        /// <param name="total">总数量</param>
        /// <param name="warehouseCode">仓库代码</param>
        /// <param name="key">关键字（区域代码/库区名称）</param>
        /// <param name="status">状态</param>
        /// <returns>库区列表</returns>
        public List<VWarehouseArea> QueryWarehouseAreas(int page, int limit, out int total, string warehouseCode, string key, CommonStatus? status)
        {
            var query = from area in mesDb.WarehouseAreas.Where(_ => _.Valid)
                        select area;
            if (!string.IsNullOrWhiteSpace(warehouseCode))
            {
                query = query.Where(_ => _.WarehouseCode == warehouseCode);
            }
            if (!string.IsNullOrWhiteSpace(key))
            {
                query = query.Where(_ => _.AreaCode.Contains(key) || _.AreaName.Contains(key));
            }
            if (status.HasValue)
            {
                query = query.Where(_ => _.Status == status.Value);
            }

            total = query.Count();

            query = query.OrderBy(_ => _.WarehouseCode).ThenBy(_ => _.AreaCode);

            var entities = limit <= 0 ? query.ToList() : query.Skip((page - 1) * limit).Take(limit).ToList();
            var models = Mapper.Map<List<VWarehouseArea>>(entities);
            return models;
        }

        /// <summary>
        /// 修改仓库状态
        /// </summary>
        /// <param name="model">仓库对象</param>
        public void ModifyStatus(VWarehouse model)
        {
            var entity = mesDb.Warehouses.FirstOrDefault(_ => _.PkId == model.PkId && _.Valid);
            if (entity == null)
            {
                throw new MultiLanBizException(103004);// "仓库不存在，无法编辑");
            }

            mesDb.Warehouses.Attach(entity);
            entity.Status = model.Status;
            entity.ModifyBy = model.ModifyBy;
            entity.ModifyTime = DateTime.Now;
            mesDb.SaveChanges();
        }

        /// <summary>
        /// 查询用户仓库
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>仓库列表</returns>
        public List<VUserWarehouse> QueryUserWarehouses(int userId)
        {
            var entities = mesDb.UserWarehouses.Where(_ => _.UserId == userId && _.Valid).ToList();
            return Mapper.Map<List<VUserWarehouse>>(entities);
        }

        /// <summary>
        /// 添加仓库用户
        /// </summary>
        /// <param name="warehouseCode">仓库代码</param>
        /// <param name="userName">用户名</param>
        /// <param name="operator">操作人ID</param>
        public VUser AddWarehouseUser(string warehouseCode, string userName, int @operator)
        {
            var warehouse = GetWarehouse(warehouseCode);
            if (warehouse == null)
            {
                throw new MultiLanBizException(103011);//仓库不存在
            }
            var user = new UserMgr().GetUser(0, userName);
            if (user == null)
            {
                throw new MultiLanBizException(103012);//用户名不存在
            }
            var warehouseUser = mesDb.UserWarehouses.AsNoTracking().FirstOrDefault(_ => _.WarehouseCode == warehouseCode && _.UserId == user.PkId && _.Valid); //new UserWarehouse
            if (warehouseUser != null)
            {
                throw new MultiLanBizException(103013);//仓库用户已存在
            }

            var existWarehouses = mesDb.UserWarehouses.AsNoTracking().Where(_ => _.WarehouseCode == warehouseCode && _.UserId == user.PkId && _.Valid).ToList(); //new UserWarehouse
            warehouseUser = new UserWarehouse
            {
                UserId = user.PkId,
                WarehouseCode = warehouse.WarehouseCode,
                WarehouseName = warehouse.WarehouseName,
                WorkshopCode = warehouse.WorkshopCode,
                WorkshopName = warehouse.WorkshopName,
                WarehouseType = warehouse.WarehouseType,
                IsDefault = !existWarehouses.Any(_ => _.IsDefault),
                CreateBy = @operator,
                CreateTime = DateTime.Now
            };
            mesDb.UserWarehouses.Add(warehouseUser);
            mesDb.SaveChanges();

            return user;
        }

        /// <summary>
        /// 移除仓库用户
        /// </summary>
        /// <param name="warehouseCode">仓库代码</param>
        /// <param name="userName">用户名</param>
        /// <param name="operator">操作人ID</param>
        public void RemoveWarehouseUser(string warehouseCode, string userName, int @operator)
        {
            var user = new UserMgr().GetUser(0, userName);
            if (user == null)
            {
                throw new MultiLanBizException(103012);//用户名不存在
            }
            var warehouseUser = mesDb.UserWarehouses.FirstOrDefault(_ => _.WarehouseCode == warehouseCode && _.UserId == user.PkId && _.Valid);
            if (warehouseUser == null)
            {
                throw new MultiLanBizException(103014);//仓库用户记录不存在
            }

            warehouseUser.Valid = false;
            warehouseUser.ModifyBy = @operator;
            warehouseUser.ModifyTime = DateTime.Now;
            mesDb.SaveChanges();
        }

        /// <summary>
        ///查询仓库用户
        /// </summary>
        /// <param name="warehouseCode">仓库代码</param>
        /// <param name="userName">用户名</param>
        /// <param name="userId">操作人ID</param>
        public List<VUser> QueryWarehouseUsers(string warehouseCode)
        {
            var users = (from uw in mesDb.UserWarehouses
                         join user in mesDb.Users on uw.UserId equals user.PkId
                         where uw.Valid && user.Valid && uw.WarehouseCode == warehouseCode
                         select user).ToList();
            return Mapper.Map<List<VUser>>(users);
        }

        /// <summary>
        /// 查询车间仓库存
        /// </summary>
        /// <param name="page">页面索引</param>
        /// <param name="limit">页面容量</param>
        /// <param name="total">全部数量</param>
        /// <param name="warehouseCodes">仓库代码</param>
        /// <param name="category">分类信息</param>
        /// <param name="product">物料信息</param>
        /// <param name="batchNo">批次号</param>
        /// <param name="storageStatus">库存状态</param>
        /// <returns>库存</returns>
        public List<VStorage> QueryWorkshopWarehouseStorages(int page, int limit, out int total, List<string> warehouseCodes, string category, string product, string batchNo, bool? storageStatus)
        {
            var query = mesDb.Storages.AsNoTracking().Where(_ => warehouseCodes.Contains(_.WarehouseCode) && _.Valid);
            if (!string.IsNullOrWhiteSpace(category))
            {
                query = query.Where(_ => _.CategoryCode.Contains(category) || _.CategoryName.Contains(category));
            }
            if (!string.IsNullOrWhiteSpace(product))
            {
                query = query.Where(_ => _.ProductCode.Contains(product) || _.ProductName.Contains(product));
            }
            if (!string.IsNullOrWhiteSpace(batchNo))
            {
                query = query.Where(_ => _.PackBatchNo.Contains(batchNo));
            }
            if (storageStatus == true)
            {
                query = query.Where(_ => _.Quantity > 0);
            }
            if (storageStatus == false)
            {
                query = query.Where(_ => _.Quantity <= 0);
            }
            total = query.Count();
            query = query.OrderByDescending(_ => _.CategoryName).ThenBy(_ => _.ProductName);

            var entities = limit <= 0 ? query.ToList() : query.Skip((page - 1) * limit).Take(limit).ToList();

            return Mapper.Map<List<VStorage>>(entities);
        }

        /// <summary>
        /// 查询货品库存
        /// </summary>
        /// <param name="page">页面索引</param>
        /// <param name="limit">页面容量</param>
        /// <param name="total">全部数量</param>
        /// <param name="customerCode">客户代码</param>
        /// <param name="orderNo">订单号</param>
        /// <param name="workOrderNo">工单号</param>
        /// <param name="cabinetNo">柜号</param>
        /// <param name="packNo">包装编号</param>
        /// <returns>货品库存列表</returns>
        public List<VStorage> QueryProductStorages(int page, int limit, out int total, string customerCode, string orderNo, string workOrderNo, string cabinetNo, string packNo)
        {
            var query = mesDb.Storages.AsNoTracking().Where(_ => _.InventoryType == InventoryType.ProductPack && _.Valid);
            if (!string.IsNullOrWhiteSpace(customerCode))
            {
                query = query.Where(_ => _.CustomerCode == customerCode);
            }
            if (!string.IsNullOrWhiteSpace(orderNo))
            {
                query = query.Where(_ => _.OrderNo.Contains(orderNo));
            }
            if (!string.IsNullOrWhiteSpace(workOrderNo))
            {
                query = query.Where(_ => _.WorkOrderNo.Contains(workOrderNo));
            }
            if (!string.IsNullOrWhiteSpace(cabinetNo))
            {
                query = query.Where(_ => _.CabinetNo.Contains(cabinetNo));
            }
            if (!string.IsNullOrWhiteSpace(packNo))
            {
                query = query.Where(_ => _.PackNo.Contains(packNo));
            }
            total = query.Count();
            query = query.OrderBy(_ => _.WarehouseCode).ThenBy(_ => _.AreaCode).ThenBy(_ => _.Location);
            var storages = limit <= 0 ? query.ToList() : query.Skip((page - 1) * limit).Take(limit).ToList();

            return Mapper.Map<List<VStorage>>(storages);
        }
    }
}
